package com.qc31.monitorlib.ui.line

import android.graphics.Color
import android.view.View
import android.widget.SeekBar
import androidx.core.view.isVisible
import androidx.fragment.app.activityViewModels
import autodispose2.autoDispose
import com.amap.api.maps.AMap
import com.amap.api.maps.CameraUpdateFactory
import com.amap.api.maps.model.*
import com.qc31.baselib.interfaces.SimpleSeekBarChangeListener
import com.qc31.baselib.rx.clickThrottle
import com.qc31.baselib.rx.queryThrottle
import com.qc31.baselib.utils.CacheMMKV
import com.qc31.baselib.utils.Language
import com.qc31.baselib.utils.formitNumberD
import com.qc31.comlib.entity.HistoryLine
import com.qc31.monitorlib.movepoint.MovePointOverlay
import com.qc31.monitorlib.R
import com.qc31.monitorlib.base.BaseMapFragment
import com.qc31.monitorlib.color.ColorsPopup
import com.qc31.monitorlib.databinding.FragmentMapLineBinding
import com.qc31.monitorlib.movepoint.MovePointListener
import com.qc31.monitorlib.movepoint.MovePointUtil
import com.qc31.monitorlib.uitls.MapUtil

/** @Author Jasper @Time 2020/8/11 @Desc 历史轨迹碎片 */
class MapLineFragment :
    BaseMapFragment<FragmentMapLineBinding>(FragmentMapLineBinding::inflate) {
    private var pointOverlay: MovePointOverlay? = null
    private var addPolyline: Polyline? = null
    private var isShowTotal = false
    private val mAllPoints = ArrayList<LatLng>()

    //起点里程
    private var firstMile = 0f

    private var isFinish = false

    //没改变的时间
    var mNotChangeTime = 15
    private var countEntity: HistoryLine.CountData? = null
    private var mLocations: List<HistoryLine.Location>? = null

    //线条颜色
    var lineColor: String
        get() = CacheMMKV.decodeString("line_color", "#6C736B")
        set(value) {
            CacheMMKV.encode("line_color", value)
        }

    private val moveOptions: PolylineOptions by lazy {
        PolylineOptions().width(lineWidth).color(Color.parseColor(lineColor))
    }
    private var movePolyline: Polyline? = null
    private var lineWidth: Float = 20f
    private val mActivityVM by activityViewModels<LineInfoViewModel>()

    override fun initView(view: View) {
        mMap?.run {
            MapUtil.initMapSetting(this)
            setOnMarkerClickListener { true }
            pointOverlay = MovePointOverlay(
                this,
                BitmapDescriptorFactory.fromResource(R.mipmap.ic_marker_move)
            )

        }
        binding.tvStartPoint.isSelected = Language.instance.isEnglish()
        binding.tvEndPoint.isSelected = Language.instance.isEnglish()
        binding.ivLineColor.setBackgroundColor(Color.parseColor(lineColor))
    }

    override fun initData() {
        mActivityVM.data.observe(this) {
            countEntity = it.countData
            mLocations = it.locations
            binding.ivLineColor.postDelayed({
                initView(it)
            }, 300)
        }

    }

    /** 暂停播放 */
    fun stopMove() {
        pointOverlay?.pauseMove()
        binding.ivLinePlayPause.setImageResource(R.mipmap.ic_line_pause)
    }

    //是否显示当前位置信息
    private var isShowInfo = false

    override fun initEvent() {
        //详情
        binding.tvLineInfo.setOnClickListener {
            isShowInfo = true
            binding.llPointInfo.isVisible = true
            binding.ivLineClose.isVisible = true
            initPointView(mLocations!![binding.linePointSeekBar.progress])
        }

        binding.ivLineClose.setOnClickListener {
            isShowInfo = false
            binding.llPointInfo.isVisible = false
            binding.ivLineClose.isVisible = false
        }

        //播放暂停
        binding.ivLinePlayPause.queryThrottle().autoDispose(scopeProvider).subscribe {
            if (isFinish) {
                isFinish = false
                moveOptions.points.clear()
                movePolyline?.options = moveOptions
            }
            isShowTotal = false
            binding.llTotalData.visibility = View.GONE
            binding.llStartEnd.visibility = View.GONE
            binding.llLineSetting.visibility = View.GONE
            binding.cbAllData.isChecked = false
            binding.cbLineSetting.isChecked = false
            pointOverlay?.startPause()
        }

        //停止
        binding.ivLineStop.queryThrottle().autoDispose(scopeProvider).subscribe {
            binding.linePointSeekBar.progress = 0
            pointOverlay?.reset()
            movePolyline?.remove()
            movePolyline = null
        }

        //设置
        binding.cbLineSetting.queryThrottle().autoDispose(scopeProvider).subscribe {
            if (binding.llLineSetting.visibility == View.GONE) {
                binding.llLineSetting.visibility = View.VISIBLE
            } else {
                binding.llLineSetting.visibility = View.GONE
            }
        }

        binding.tvLineMapState.queryThrottle().autoDispose(scopeProvider).subscribe {
            mMap?.run {
                mapType = if (mapType == AMap.MAP_TYPE_NORMAL) {
                    binding.tvLineMapState.setText(R.string.desc_com_map_state_satellite)
                    AMap.MAP_TYPE_SATELLITE
                } else {
                    binding.tvLineMapState.setText(R.string.desc_com_map_state_normal)
                    AMap.MAP_TYPE_NORMAL
                }
            }
        }

        binding.cbAllData.setOnClickListener {
            isShowTotal = !isShowTotal
            binding.llTotalData.isVisible = isShowTotal
            binding.llStartEnd.isVisible = isShowTotal
        }

        binding.ivLineColor.clickThrottle().autoDispose(scopeProvider).subscribe {
            changeColor()
        }

        pointOverlay?.setMovePointListener(object : MovePointListener {
            override fun current(index: Int, fromPoint: LatLng, toPoint: LatLng) {
                requireActivity().runOnUiThread {
                    binding.linePointSeekBar.progress = index
                    if (isShowInfo) initPointView(mLocations!![index])
                }
                mMap?.let {
                    //计算是否在屏幕内
                    val latLngBounds = it.projection.visibleRegion.latLngBounds
                    if (!latLngBounds.contains(toPoint)) {
                        it.animateCamera(CameraUpdateFactory.newLatLng(toPoint))
                    }
                }
            }

            override fun moving(latLng: LatLng) {
                if (movePolyline == null) {
                    moveOptions.points = arrayListOf(latLng)
                    movePolyline = mMap?.addPolyline(moveOptions)
                    MapUtil.showMapLatLng(mMap!!, latLng)
                } else {
                    moveOptions.add(latLng)
                    movePolyline?.options = moveOptions
                }
            }


            override fun startPause(isStart: Boolean) {
                requireActivity().runOnUiThread {
                    if (isStart) {
                        binding.ivLinePlayPause.setImageResource(R.mipmap.ic_line_play)
                    } else {
                        binding.ivLinePlayPause.setImageResource(R.mipmap.ic_line_pause)
                    }
                }
            }

            override fun finish() {
                isFinish = true
                requireActivity().runOnUiThread {
                    binding.ivLinePlayPause.setImageResource(R.mipmap.ic_line_pause)
                }
            }
        })
    }


    /** 初始化View */
    fun initView(entity: HistoryLine) {
        val list: List<HistoryLine.Location> = entity.locations
        firstMile = list.first().mile.toFloat()
        for (item in entity.locations) {
            item.dmile = formitNumberD("2", item.mile.toFloat() - firstMile).toString()
            mAllPoints.add(LatLng(item.glat.toDouble(), item.glng.toDouble()))
        }
        pointOverlay?.setPoints(mAllPoints)

        binding.linePointSeekBar.max = mAllPoints.size - 1
        binding.linePointSeekBar.setOnSeekBarChangeListener(object : SimpleSeekBarChangeListener {
            override fun onStopTrackingTouch(seekBar: SeekBar?) {
                super.onStopTrackingTouch(seekBar)
                seekBar?.run {
                    pointOverlay?.change(progress)
                    initPointView(mLocations!![progress])
                    if (movePolyline == null) {
                        moveOptions.points = mAllPoints.subList(0, progress)
                        movePolyline = mMap?.addPolyline(moveOptions)
                        MapUtil.showMapLatLng(mMap!!, mAllPoints[progress])
                    } else {
                        moveOptions.points.clear()
                        MapUtil.showMapLatLng(mMap!!, mAllPoints[progress])
                        moveOptions.points = mAllPoints.subList(0, progress)
                        movePolyline?.options = moveOptions
                    }
                }
            }

            override fun onStartTrackingTouch(seekBar: SeekBar?) {
                super.onStartTrackingTouch(seekBar)
                pointOverlay?.seekbarMove()

            }
        })

        binding.lineSpeedSeekBar.max = mNotChangeTime
        binding.lineSpeedSeekBar.setOnSeekBarChangeListener(object : SimpleSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
                MovePointUtil.setSpeed(seekBar!!.progress)
            }
        })

        binding.lineWidthSeekBar.max = 10
        binding.lineWidthSeekBar.setOnSeekBarChangeListener(object : SimpleSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
                lineWidth = (progress + 20).toFloat()
                movePolyline?.width = lineWidth
                addPolyline?.width = lineWidth
            }
        })
        val startPoint = list.first()
        val endPoint = list.last()
        //开始点
        MapUtil.addMarker(
            mMap!!,
            LatLng(startPoint.glat.toDouble(), startPoint.glng.toDouble()),
            if (Language.instance.isEnglish()) R.mipmap.ic_marker_start_e else R.mipmap.ic_marker_start
        )
        //结束点
        MapUtil.addMarker(
            mMap!!,
            LatLng(endPoint.glat.toDouble(), endPoint.glng.toDouble()),
            if (Language.instance.isEnglish()) R.mipmap.ic_marker_end_e else R.mipmap.ic_marker_end
        )
        binding.tvStartPoint.text = startPoint.addr
        binding.tvEndPoint.text = endPoint.addr
        binding.tvStartEndTime.text =
            "${getString(R.string.desc_start_end_time)}：${startPoint.time}~${endPoint.time}"
        initPoints()
        initRecycler()
        binding.cbAllData.isChecked = true
    }

    /** 初始化Point */
    private fun initPoints() {
        setPolyLine()?.let {
            //移动到中心点
            MapUtil.showMapBounds(mMap!!, it)
        }

        if (mAllPoints.isEmpty()) {
            return
        }
        //画线 有需要可以参照其它画线功能添加图片
        val polylineOptions = PolylineOptions()
        polylineOptions.points = mAllPoints
        polylineOptions.width(lineWidth).customTexture =
            BitmapDescriptorFactory.fromResource(R.mipmap.ic_line_custtexture)
        polylineOptions.isDottedLine = true
        addPolyline = mMap?.addPolyline(polylineOptions)

    }

    private fun initPointView(entity: HistoryLine.Location) {
        binding.lrTvPointTime.setRightText(entity.time)
        binding.lrTvPointSpeed.setRightText("${entity.speed} ${getString(R.string.unit_speed)} , ${entity.drctCn}")

        binding.lrTvPointMile.setRightText("${entity.dmile} ${getString(R.string.unit_mile)}")
        binding.tvPointAddress.text = entity.addr
    }

    ////////////////////////////////////////整体数据//////////////////////////////////////////////
    private fun initRecycler() {
        val list: HistoryLine.CountData = countEntity!!
        binding.lrTvSpeedTime.setRightText(list.moveLong)
        binding.lrTvSpeedMax.setRightText("${list.maxSpeed} km/h")
        binding.lrTvStopTime.setRightText(list.stopLong)
        binding.lrTvStopAverage.setRightText("${list.avgSpeed} km/h")
        binding.lrTvRunMile.setRightText("${list.mile} km")
        binding.lrTvLocationNum.setRightText("${list.gpsSize} ${getString(R.string.desc_unit_num)}")
    }

    private val mPopup by lazy {
        ColorsPopup(
            requireContext(),
            R.string.dialog_choose_line_color,
            colorCallback
        )
    }
    private val colorCallback = object : ColorsPopup.Callback {
        override fun callback(index: Int, color: String) {
            lineColor = color
            binding.ivLineColor.setBackgroundColor(Color.parseColor(color))
            movePolyline?.color = Color.parseColor(color)
        }

    }

    private fun changeColor() {
        mPopup.showPopup(requireActivity().window.decorView, lineColor)
    }

    /** 设置轨迹线 */
    private fun setPolyLine(): LatLngBounds? {
        mLocations?.run {
            mAllPoints.clear();
            val bounds = LatLngBounds.builder()
            for (location in this) {
                val latLng = LatLng(location.glat.toDouble(), location.glng.toDouble())
                mAllPoints.add(latLng)
                bounds.include(latLng)
            }
            return bounds.build()
        }
        return null
    }

    override fun onDestroy() {
        super.onDestroy()
        pointOverlay?.destroy()
        pointOverlay = null
    }
}